package com.hongxun.design.utils.gpsutil;

import android.content.Context;
import android.content.Intent;
import android.location.Criteria;
import android.location.GpsSatellite;
import android.location.GpsStatus;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;

import com.alibaba.fastjson.JSON;
import com.hongxun.design.MyApp;
import com.hongxun.design.constant.Constant;
import com.hongxun.design.mytools.MString;
import com.hongxun.design.mytools.MyDecimalFormat;
import com.hongxun.design.mytools.MyLog;
import com.hongxun.design.mytools.ShardPreferencesTool;
import com.hongxun.design.mytools.ToastShow;
import com.hongxun.design.object_properties.MyMessage;
import com.hongxun.design.utils.httputil.HttpStringUtil;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * Created by zerdoor_pc on 2016/1/28.
 */
public class GPS_TOOL {
    private Context context;
    private String TAG = MString.SUCCESSED + "GPS";
    public static boolean isOn=true;
    GPS_TOOL(Context context) {

        this.context = context;

    }

    static GPS_TOOL intence;

    public static GPS_TOOL getIntence(Context context) {
        if (intence == null) {
            intence = new GPS_TOOL(context);

        }
        isOn=true;

        return intence;
    }


    public void close() {
        times=0;
        onActivityDestroy();
        intence = null;
    }

    public Intent intent;

    public Boolean openGPSSettings() {
        times=0;
        LocationManager alm = (LocationManager) context
                .getSystemService(Context.LOCATION_SERVICE);
        if (alm.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER)) {
            try {

                //ToastShow.showShort(context, "GPS模块正常");
            } catch (Exception e) {
            }
            MyLog.L("MYGPSDEMO=GPS模块正常");
            //getLocation();
            return true;
        }
        try {
            MyLog.L("MYGPSDEMO=请开启GPS");
            //ToastShow.showShort(context, "GPS尚未开启！");
        } catch (Exception e) {
        }
        intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);

        //context.startActivity(intent);
        //context.startActivityForResult(intent, 0); //此为设置完成后返回到获取界面
        return false;

    }

    public Boolean checkGPS() {
        LocationManager alm = (LocationManager) context
                .getSystemService(Context.LOCATION_SERVICE);
        if (alm.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER)) {
            ToastShow.showShort(context, "GPS模块正常");
            getLocation();
            MyLog.L("MYGPSDEMO=GPS模块正常2");

            return true;
        }
        ToastShow.showShort(context, "请开启GPS");
        MyLog.L("MYGPSDEMO=请开启GPS2");
        return false;
    }

    LocationManager locationManager;
    String provider;
    public void getLocation() {
        // 获取位置管理服务
        if (!isOn)return;
        flag = 0;
        ShardPreferencesTool.saveshare(context, code, "");
        String serviceName = Context.LOCATION_SERVICE;
        MyApp.change=false;
        if (locationManager == null) {
            locationManager = (LocationManager) context.getSystemService(serviceName);
            // 查找到服务信息
            provider = locationManager.getBestProvider(getCriteria(), true); // 获取GPS信息
            Location location = locationManager.getLastKnownLocation(provider);
            updateToNewLocation(location);
            //监听状态
            locationManager.addGpsStatusListener(listener);
            // 设置监听器，自动更新的最小时间为间隔N秒(1秒为1*1000，这样写主要为了方便)或最小位移变化超过N米
        }
        if (provider == null)
            provider = locationManager.getBestProvider(getCriteria(), true); // 获取GPS信息

//        locationManager.requestLocationUpdates(provider, MyApp.time * 1000, MyApp.distence,
//                locationListener);
        locationManager.requestLocationUpdates(provider, 1000, 5,locationListener);

    }

    private void getLocationGPS(){
        if (provider == null) provider = locationManager.getBestProvider(getCriteria(), true); // 获取GPS信息
        Location location = locationManager.getLastKnownLocation(provider);
        updateToNewLocation(location);
    }

    public void setTimes() {
        String provider = locationManager.getBestProvider(getCriteria(), true); // 获取GPS信息
        locationManager.requestLocationUpdates(provider, MyApp.time * 1000, MyApp.distence,
                locationListener);
    }


    public void onActivityDestroy() {
        try {
             isOn =false;
            locationManager.clearTestProviderEnabled(locationManager.getBestProvider(getCriteria(), true));
            locationManager.removeGpsStatusListener(listener);
            locationManager.removeUpdates(locationListener);
        }catch (Exception e){}

    }

    /**
     * 返回查询条件
     *
     * @return
     */
    public Criteria getCriteria() {
        Criteria criteria = new Criteria();
        //设置定位精确度 Criteria.ACCURACY_COARSE比较粗略，Criteria.ACCURACY_FINE则比较精细
        criteria.setAccuracy(Criteria.ACCURACY_FINE);
        //设置是否要求速度
        criteria.setSpeedRequired(true);
        // 设置是否允许运营商收费
        criteria.setCostAllowed(false);
        //设置是否需要方位信息
        criteria.setBearingRequired(true);
        //设置是否需要海拔信息
        criteria.setAltitudeRequired(true);
        // 设置对电源的需求
//        criteria.setPowerRequirement(Criteria.POWER_MEDIUM);
        criteria.setPowerRequirement(MyApp.POWER);

        return criteria;
    }


    List<Location> data = new ArrayList<>();
    List<Location> currdata = new ArrayList<>();
    String code = "saveGPS_";

    double min = 1000.0;
    double max = 0.0;

    Location location;
    double latitude;
    double longitude;
    float accuracy;
    public int flag = 0;

    public void updateToNewLocation(Location location) {
        if (!isOn)return;
        if (location != null) {
            this.location = location;
            latitude = location.getLatitude();
            longitude = location.getLongitude();
            accuracy = location.getAccuracy();
            String s =" \n精度:" + accuracy + " 卫星数：" + oldcount + "\n经度：" + longitude + " \n 纬度：" + latitude;
            String s2=ShardPreferencesTool.getshare(context,code,"");
            ShardPreferencesTool.saveshare(context, code, s2 + s);
           // ToastShow.showShort(context, "GPS更新:  " + s);
//            ToastShow.showShort(context, "GPS更新:  精度:" + accuracy + " 卫星数：" + oldcount);
           // ToastShow.showShort(context,s);
//            accuracy > MyApp.GPSACCURACY ||
            if (oldcount < 8) {
//            if (false){
                if (data.size()>0){
                    data.clear();
                    sendUpdateCode2("校验失败，正在重新开始！");
                }else{
                    sendUpdateCode2("获取数据中！");
                }
                sendUpdateCode(location);
            } else {
                sendUpdateCode(location);
                if (flag == 0) {
                    flag = 1;
                    handler.sendEmptyMessage(2);//开始遍历
                }else if (flag == 2){
                    flag = 1;
                    handler.sendEmptyMessage(2);
                    MyApp.handler.sendEmptyMessage(Constant.GPSOpenDialog);
                }


            }
        } else {
            // ToastShow.showShort(context, "正在获取地理信息");
            //tv1.setText("无法获取地理信息");
            //ToastShow.showShort(context, "无法获取地理信息");
            MyLog.L("无法获取地理信息");
        }

    }
    public void updateToNewLocationChange(Location location) {
        if (location != null) {
            this.location = location;
            latitude = location.getLatitude();
            longitude = location.getLongitude();
            accuracy = location.getAccuracy();
            sendUpdateCode(location);
            String s =" \n精度:" + accuracy + " 卫星数：" + oldcount + "\n经度：" + longitude + " \n 纬度：" + latitude;
           // ToastShow.showShort(context, "位移 " +s);
            if (accuracy > MyApp.GPSACCURACY || oldcount < 8) {
                if (data.size()>0){
                    data.clear();
                    sendUpdateCode2("校验失败，正在重新开始！");
                }else{
                    sendUpdateCode2("获取数据中！");
                }

            } else {
                sendUpdate(location);//更新
                if (flag == 1) {
                    flag = 2;
                    handler.sendEmptyMessage(1);
                }

            }
        } else {
            MyLog.L("无法获取地理信息");
        }

    }

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case 1:
                    getGps();
                    //更新
                    break;
                case 2:
                    start();//开始循环
                    break;
            }


        }
    };

    int times=0;
    private void start() {
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                //getLocationGPS();
                getGps();
            }
        }, 1000);
    }

    private void getGps(){
        if (!isOn)return;
        if (location!=null){
            times++;

            if (data.size()>0&& MyDecimalFormat.getDouble_6(data.get(0).getLatitude())  == MyDecimalFormat.getDouble_6(latitude) && MyDecimalFormat.getDouble_6(data.get(0).getLongitude()) == MyDecimalFormat.getDouble_6(longitude)) {
                data.add(location);//加入数据集
            } else {
                data.clear();
                sendUpdateCode2("校验失败，重新开始！");
                data.add(location);//加入数据集
            }
            if (data.size() >= 5) {
                sendUpdateCode2("校验成功！");
                sendUpdate(location);//更新
                data.clear();
                flag = 2;
                times=0;
            } else if (times>=60){
                sendUpdateCode2("校验超时！");
                sendCloseUpdate(location);//更新
                data.clear();
                flag = 2;
            }else {
                sendUpdateCode2("正在校验第"+data.size()+"个,还剩:"+(60-times)+"次");//+"\n纬度："+location.getLatitude()+"\n经度:"+location.getLongitude()
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                       handler.sendEmptyMessage(1);
                    }
                },1000);
            }

        }else{
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    handler.sendEmptyMessage(1);
                }
            },1000);
        }
    }


    private void sendUpdateCode(Location location) {
        if (!isOn)return;
        MyApp.location = location;
        MyApp.handler.sendEmptyMessage(Constant.GPSCodeUpdate);//更新code数据
        //更新信号
    }

    private void sendUpdateCode2(String s) {
        if (!isOn)return;
        MyApp.handler.sendMessage(MyMessage.getMessage(Constant.GPSCodeUpdate2,s));
        //更新字段
    }

    /**
     * 更新数据*
     */
    private void sendUpdate(Location location) {
        if (!isOn)return;
        MyApp.location = location;
        MyApp.handler.sendEmptyMessage(Constant.GPSUpdate);
        MyLog.L(HttpStringUtil.SUCCESSED + ":返回数据:" + JSON.toJSONString(location));
        MyLog.L(HttpStringUtil.SUCCESSED + "\n维度：" + location.getLatitude() + "\n经度" + location.getLongitude());

    }

    /**
     * 超时更新数据*
     */
    private void sendCloseUpdate(Location location) {
        if (!isOn)return;
        MyApp.location = location;
        MyApp.handler.sendEmptyMessage(Constant.GPSCloseUpdate);
        MyLog.L(HttpStringUtil.SUCCESSED + ":返回数据:" + JSON.toJSONString(location));
        MyLog.L(HttpStringUtil.SUCCESSED + "\n维度：" + location.getLatitude() + "\n经度" + location.getLongitude());

    }

    private LocationListener locationListener = new LocationListener() {

        /**
         * 位置信息变化时触发
         */
        public void onLocationChanged(Location location) {
            MyLog.L("HTTPURL：当前GPS位置变化");
            //updateToNewLocationChange(location);
            //MyApp.change=true;
            updateToNewLocation(location);
        }


        /**
         * GPS状态变化时触发
         */
        public void onStatusChanged(String provider, int status, Bundle extras) {

            switch (status) {
                //GPS状态为可见时
                case LocationProvider.AVAILABLE:
                    MyLog.L(TAG + "当前GPS状态为可见状态");
                    Location location = locationManager.getLastKnownLocation(provider);
                    //updateToNewLocation(location);
                    break;
                //GPS状态为服务区外时
                case LocationProvider.OUT_OF_SERVICE:
                    MyLog.L(TAG + "当前GPS状态为服务区外状态");
                    break;
                //GPS状态为暂停服务时
                case LocationProvider.TEMPORARILY_UNAVAILABLE:
                    MyLog.L(TAG + "当前GPS状态为暂停服务状态");
                    break;
            }
        }

        /**
         * GPS开启时触发
         */
        public void onProviderEnabled(String provider) {
            if (!isOn)return;
            Location location = locationManager.getLastKnownLocation(provider);
            //updateToNewLocation(location);
        }

        /**
         * GPS禁用时触发
         */
        public void onProviderDisabled(String provider) {
            updateToNewLocation(null);
        }


    };


    //状态监听
    GpsStatus.Listener listener = new GpsStatus.Listener() {
        public void onGpsStatusChanged(int event) {
            if (!isOn)return;

            switch (event) {
                //第一次定位
                case GpsStatus.GPS_EVENT_FIRST_FIX:
                    MyLog.L(TAG + "第一次定位");
                    break;
                //卫星状态改变
                case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
                    MyLog.L(TAG + "卫星状态改变");
                    //获取当前状态
                    GpsStatus gpsStatus = locationManager.getGpsStatus(null);
                    //获取卫星颗数的默认最大值
                    int maxSatellites = gpsStatus.getMaxSatellites();
                    //创建一个迭代器保存所有卫星
                    Iterator<GpsSatellite> iters = gpsStatus.getSatellites().iterator();
                    int count = 0;
                    while (iters.hasNext() && count <= maxSatellites) {
                        GpsSatellite s = iters.next();
                        count++;
                    }
                    oldcount = count;
                    MyLog.L(TAG + "搜索到：" + count + "颗卫星");

                    break;
                //定位启动
                case GpsStatus.GPS_EVENT_STARTED:
                    MyLog.L(TAG + "定位启动");
                    break;
                //定位结束
                case GpsStatus.GPS_EVENT_STOPPED:
                    MyLog.L(TAG + "定位结束");
                    break;
            }
        }

    };
    int oldcount = 0;//卫星数

    public int getCount() {
        return oldcount;
    }


}

//    public void updateToNewLocation(Location location) {
//        if (location != null) {
//            double latitude = location.getLatitude();
//            double longitude = location.getLongitude();
//
//            float accuracy = location.getAccuracy();
//            if (accuracy > MyApp.GPSACCURACY || oldcount < 8) {
//                ToastShow.showShort(context, "精度:" + accuracy + " 卫星数：" + oldcount);
//                sendUpdateCode(location);
//            } else {
////              ToastShow.showShort(context,"精度:" + accuracy + " 卫星数：" + oldcount );
//                sendUpdateCode(location);
//                data.add(location);//加入数据集
//                if (data.size()>=100){
//                    data.remove(0);
//                }
//                if (data.size() >= MyApp.currSize) {
//                //数据集个数满足
//                    currdata.clear();
//                    for (int i = 1; i <= 5; i++) {
//                        currdata.add(data.get(data.size() - i));
//                    }
//
//                    /**计算纬度是否达标**/
//                    min = 1000.0;
//                    max = 0.0;
//                    for (Location l : currdata) {
//                        if (min > l.getLatitude()) {
//                            min = l.getLatitude();
//                        }
//                        if (max < l.getLatitude()) {
//                            max = l.getLatitude();
//                        }
//                    }
//
//                    if ((max - min) > MyApp.curr_lat) {
//                        sendUpdateCode(location);
//                        min = 1000.0;
//                        max = 0.0;
//                        return;
//                    }
//                    /**计算经度是否达标**/
//                    min = 1000.0;
//                    max = 0.0;
//                    for (Location l : currdata) {
//                        if (min > l.getLongitude()) {
//                            min = l.getLongitude();
//                        }
//                        if (max < l.getLongitude()) {
//                            max = l.getLongitude();
//                        }
//                    }
//
//                    if ((max - min) > MyApp.curr_lon) {
//                        sendUpdateCode(location);
//                        min = 1000.0;
//                        max = 0.0;
//                        return;
//                    }
//                    /**更新数据**/
//                    sendUpdate(location);//第五次时更新
//
//
//                }
////                if (flag<100){
////                    //ToastShow.showLong(context,code+"采集第"+flag+"个：");
////                    flag++;
////                    String s2=ShardPreferencesTool.getshare(context,code,"");
////                    ShardPreferencesTool.saveshare(context, code, s2 + " \n精度:" + accuracy + " 卫星数：" + oldcount + "\n经度：" + longitude + "  纬度：" + latitude);
////                }else{
////                    ToastShow.showLong(context,"采集完毕！"+code);
////                    code=code+"1";
////                    flag=0;
////                }
//            }
//        } else {
//            // ToastShow.showShort(context, "正在获取地理信息");
//            //tv1.setText("无法获取地理信息");
//            MyLog.L("无法获取地理信息");
//        }
//
//    }